package com.yueyang.sojourn.server.controller.project;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;
import com.yueyang.sojourn.server.common.baymax.web.result.JAssert;
import com.yueyang.sojourn.server.config.WxPayProperties;
import com.yueyang.sojourn.server.controller.BaseController;
import com.yueyang.sojourn.server.controller.model.JsonResult;
import com.yueyang.sojourn.server.model.dto.EditBannerDto;
import com.yueyang.sojourn.server.model.dto.EditProjectShareDto;
import com.yueyang.sojourn.server.model.po.SojournMerchant;
import com.yueyang.sojourn.server.model.po.SojournProject;
import com.yueyang.sojourn.server.model.po.SojournProjectShare;
import com.yueyang.sojourn.server.model.po.SojournProjectShareLog;
import com.yueyang.sojourn.server.model.vo.SojournProjectShareLogVo;
import com.yueyang.sojourn.server.model.vo.SojournProjectShareVo;
import com.yueyang.sojourn.server.service.sojourn.merchant.SojournMerchantService;
import com.yueyang.sojourn.server.service.sojourn.project.SojournProjectService;
import com.yueyang.sojourn.server.service.sojourn.projectshare.SojournProjectShareLogService;
import com.yueyang.sojourn.server.service.sojourn.projectshare.SojournProjectShareService;
import com.yueyang.uc.model.UcUserV1;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author Andy.yang
 * @version v1
 * @summary
 * @Copyright (c) 2019, YueYang Group All Rights Reserved.
 * @since 2020/3/24
 */
@RestController
@Slf4j
@Api(tags = "项目分账配置 API")
@RequestMapping("/sojourn/project")
public class  SojournProjectShareController extends BaseController {
    @Autowired
    SojournProjectShareService projectShareService;
    @Autowired
    SojournMerchantService merchantService;
    @Autowired
    SojournProjectShareLogService shareLogService;
    @Autowired
    SojournProjectService projectService;
    @Autowired
    WxPayProperties properties;

    /**
     * 创建
     * @param sharesDto
     * @return
     */
    @ApiImplicitParam(name = "X-Token", paramType = "header", required = true)
    @ApiOperation(value = "创建分账配置")
    @PostMapping("/{projectId}/share")
    public JsonResult<Long> createOrUpdateShare(@PathVariable("projectId") Long projectId,
                                                @RequestBody @Validated List<EditProjectShareDto> sharesDto, BindingResult bindingResult) {
        FieldError fieldError = bindingResult.getFieldError();
        if (Objects.nonNull(fieldError)) {
            JAssert.justFailed(fieldError.getDefaultMessage());
        }

        UcUserV1 ucUserV1 = super.getLoginUser();
        long loginUserId = ucUserV1.getId();

        SojournProject project = projectService.selectByPrimaryKey(projectId);
        if(project == null){
            return fail("项目不存在");
        }
        SojournMerchant merchantMain = merchantService.findByProjectId(projectId);
        if(merchantMain == null){
            return fail("项目还未绑定商户");
        }

        //验证
        List<Long> receiverIds = new ArrayList<>();
        Map<Long,SojournProjectShare> projectSharesOld = projectShareService.findMapByProjectId(projectId);
        boolean haveMainMerchant = false;
        BigDecimal totalRatio = new BigDecimal(0);
        for(EditProjectShareDto dto : sharesDto){
            if(dto.getShareRatio().compareTo(BigDecimal.ZERO) == 0 || dto.getShareRatio().compareTo(BigDecimal.ZERO) == -1){
                return fail("分账比例不能小于0");
            }
            totalRatio = totalRatio.add(dto.getShareRatio());
            if(totalRatio.compareTo(new BigDecimal(100)) == 1){
                return fail("分账比例之和超过100%，请检查");
            }

            if(dto.getReceiverId().equals(merchantMain.getId())) {
                if(dto.getShareRatio().compareTo(new BigDecimal(71)) < 0){
                    return fail("主商户分账比例低于71%，请检查");//因为有1%的手续费，也属于分账比例
                }
            }

            if(dto.getReceiverId().equals(merchantMain.getId())){
                haveMainMerchant = true;
            }
            if(receiverIds.contains(dto.getReceiverId())){
                SojournMerchant merchant = merchantService.findById(dto.getReceiverId());
                return fail("商户[" + merchant.getName() + "]已存在");
            }else{
                SojournMerchant merchant = merchantService.findById(dto.getReceiverId());
                if(merchant == null){
                    return fail("商户不存在");
                }
                if(merchant.getWxMerchantNo().equals(properties.getMchId())){
                    return fail("服务商不能配置为分账商户");
                }
                receiverIds.add(dto.getReceiverId());
            }

            if(dto.getId() != null && projectSharesOld.get(dto.getId()) == null){
                return fail("商户分账id[" + dto.getId() + "]不存在");
            }
        }

        if(receiverIds.size() > 20){
            return fail("分账方已超过20个");
        }
        if(!haveMainMerchant){
            return fail("必须配置主商户");
        }



        //更新
        projectShareService.addOrUpdateOrDel(sharesDto,projectId,loginUserId);
        return ok();
    }

    @ApiImplicitParam(name = "X-Token", paramType = "header", required = true)
    @ApiOperation(value = "根据项目id查询项目分账配置")
    @GetMapping("/{projectId}/share")
    public List<SojournProjectShareVo> find(@ApiParam(value = "项目id", required = true)
                                           @PathVariable("projectId") Long projectId) {
        List<SojournProjectShare> shares = projectShareService.findListByProjectId(projectId);

        final Map<Long,SojournMerchant> merchantMap = new LinkedHashMap<>();
        if(!shares.isEmpty()){
            List<Long> merchantIds = new ArrayList<>();
            shares.stream().forEach((share) -> {
                if(!merchantIds.contains(share.getReceiverId())){
                    merchantIds.add(share.getReceiverId());
                }
            });
            Map<Long,SojournMerchant> merchantMapTemp = merchantService.findMapByIds(merchantIds);
            merchantMap.putAll(merchantMapTemp);
        }

        List<SojournProjectShareVo> rs = new ArrayList<>();
        if(!shares.isEmpty()){
            shares.stream().forEach((share) -> {
                SojournProjectShareVo vo = new SojournProjectShareVo();
                BeanUtils.copyProperties(share,vo);
                SojournMerchant merchant = merchantMap.get(vo.getReceiverId());
                if(merchant != null) {
                    vo.setReceiverName(merchant.getName());
                    vo.setReceiverWxMerchantNo(merchant.getWxMerchantNo());
                    if(projectId.equals(merchant.getProjectId())){
                        vo.setPrime(true);
                    }
                }
                rs.add(vo);
            });
        }
        return rs;
    }


    @ApiImplicitParam(name = "X-Token", paramType = "header", required = true)
    @ApiOperation(value = "根据项目id查询项目分账修改记录")
    @GetMapping("/{projectId}/share/log")
    public PageInfo<SojournProjectShareLogVo> findShareLog(@ApiParam(value = "项目id", required = true)
                                            @PathVariable("projectId") Long projectId,
                                                           int pageSize,
                                                           int pageNo){
        PageInfo<SojournProjectShareLog> shareLogs = shareLogService.findPage(projectId,pageNo,pageSize);
        PageInfo<SojournProjectShareLogVo> rs = new PageInfo<>();
        BeanUtils.copyProperties(shareLogs,rs);
        rs.setList(new ArrayList<>());
        List<Long> userIds = new ArrayList<>();
        if(!shareLogs.getList().isEmpty()){
            shareLogs.getList().stream().forEach((shareLog) -> {
                SojournProjectShareLogVo vo = new SojournProjectShareLogVo();
                vo.setId(shareLog.getId());
                if(shareLog.getBeforeValue() != null && !shareLog.getBeforeValue().isEmpty()){
                    List<SojournProjectShareLogVo.ProjectShareVo> beforeList = JSON.parseArray(shareLog.getBeforeValue(),SojournProjectShareLogVo.ProjectShareVo.class);
                    vo.setBeforeValue(beforeList);
                }
                if(shareLog.getAfterValue() != null && !shareLog.getAfterValue().isEmpty()){
                    List<SojournProjectShareLogVo.ProjectShareVo> afterList = JSON.parseArray(shareLog.getAfterValue(),SojournProjectShareLogVo.ProjectShareVo.class);
                    vo.setAfterValue(afterList);
                }
                vo.setProjectId(shareLog.getProjectId());
                vo.setCreatedTime(shareLog.getCreatedTime());
                vo.setCreator(shareLog.getCreator());
                if(!userIds.contains(shareLog.getCreator())){
                    userIds.add(shareLog.getCreator());
                }
                rs.getList().add(vo);
            });
        }

        Map<Long,UcUserV1> userV1Map = findMapByIds(userIds);
        rs.getList().forEach((vo) -> {
            vo.setCreatorPhoneShow(userV1Map.get(vo.getCreator()) == null ? null : userV1Map.get(vo.getCreator()).getPhoneShow());
        });
        return rs;
    }
}
